#include "CellNumber.h"

#include "CatanClassContractException.h"

namespace catan
{

/*static*/ std::vector<CellNumber::Enum_CellNumber> CellNumber::vectorOfPossibleEnumValues;
/*static*/ std::vector<CellNumber::Enum_CellNumber> CellNumber::vectorOfNonDesertLandEnumValues;

/*static*/ const std::vector<CellNumber::Enum_CellNumber> &CellNumber::getVectorOfPossibleEnumValues()
{
	if (vectorOfPossibleEnumValues.empty())
	{
		vectorOfPossibleEnumValues.push_back(N_SEA);
		vectorOfPossibleEnumValues.push_back(N2);
		vectorOfPossibleEnumValues.push_back(N3);
		vectorOfPossibleEnumValues.push_back(N4);
		vectorOfPossibleEnumValues.push_back(N5);
		vectorOfPossibleEnumValues.push_back(N6);
		vectorOfPossibleEnumValues.push_back(N7_DESERT);
		vectorOfPossibleEnumValues.push_back(N8);
		vectorOfPossibleEnumValues.push_back(N9);
		vectorOfPossibleEnumValues.push_back(N10);
		vectorOfPossibleEnumValues.push_back(N11);
		vectorOfPossibleEnumValues.push_back(N12);
	}
	return vectorOfPossibleEnumValues;
}

/*static*/ const std::vector<CellNumber::Enum_CellNumber> &CellNumber::getVectorOfNonDesertLandEnumValues()
{
	if (vectorOfNonDesertLandEnumValues.empty())
	{
		vectorOfNonDesertLandEnumValues.push_back(N2);
		vectorOfNonDesertLandEnumValues.push_back(N3);
		vectorOfNonDesertLandEnumValues.push_back(N3);
		vectorOfNonDesertLandEnumValues.push_back(N4);
		vectorOfNonDesertLandEnumValues.push_back(N4);
		vectorOfNonDesertLandEnumValues.push_back(N5);
		vectorOfNonDesertLandEnumValues.push_back(N5);
		vectorOfNonDesertLandEnumValues.push_back(N6);
		vectorOfNonDesertLandEnumValues.push_back(N6);
		vectorOfNonDesertLandEnumValues.push_back(N8);
		vectorOfNonDesertLandEnumValues.push_back(N8);
		vectorOfNonDesertLandEnumValues.push_back(N9);
		vectorOfNonDesertLandEnumValues.push_back(N9);
		vectorOfNonDesertLandEnumValues.push_back(N10);
		vectorOfNonDesertLandEnumValues.push_back(N10);
		vectorOfNonDesertLandEnumValues.push_back(N11);
		vectorOfNonDesertLandEnumValues.push_back(N11);
		vectorOfNonDesertLandEnumValues.push_back(N12);
	}
	return vectorOfNonDesertLandEnumValues;
}

/*static*/ bool CellNumber::canInit(Enum_CellNumber enumCellNumber)
{
	const std::vector<CellNumber::Enum_CellNumber> enumValues = CellNumber::getVectorOfPossibleEnumValues();
	for (std::vector<CellNumber::Enum_CellNumber>::const_iterator enumValueIterator = enumValues.begin(); enumValueIterator != enumValues.end(); ++enumValueIterator)
	{
		if (enumCellNumber == *enumValueIterator)
		{
			return true;
		}
	}
	return false;
}

/*explicit*/ CellNumber::CellNumber(Enum_CellNumber enumCellNumber): enumCellNumber(enumCellNumber)
{
	if (!CellNumber::canInit(enumCellNumber))
	{
		throw CatanClassContractException(__FILE__, __LINE__, "CellNumber::canInit(...) with constructor arguments should be true before creating instance.");
	}
}

CellNumber::Enum_CellNumber CellNumber::getEnum() const
{
	return enumCellNumber;
}

bool CellNumber::operator==(const CellNumber &other) const
{
	return enumCellNumber == other.enumCellNumber;
}

bool CellNumber::operator<(const CellNumber &other) const
{
	return enumCellNumber < other.enumCellNumber;
}

CellNumber& CellNumber::operator=(const CellNumber& other)
{
    if (this != &other)
    {
        enumCellNumber = other.enumCellNumber;
    }
    return *this;	
}

}